<template>
  <view class="container">
    <view class="header">
      <text class="title">直播页面</text>
    </view>
    
    <view class="main-content">
      <!-- 主画面区域 -->
      <view class="main-video-section">
        <text class="section-title">主画面</text>
        <view class="main-video-wrapper">
          <!-- 主播视频播放 -->
          <view v-if="publisherSdk" class="main-video-container">
            <view v-html="publisherVideoElement"></view>
            <text class="video-label local-label">主播画面</text>
          </view>
          
          <!-- 无主播流时的占位符 -->
          <view v-else class="placeholder">
            <text v-if="status === 'connecting'">正在连接...</text>
            <text v-else-if="status === 'error'">连接错误: {{ errorMessage }}</text>
            <text v-else-if="status === 'connected'">等待主播开播...</text>
            <text v-else>等待操作...</text>
          </view>
          
          <!-- 弹幕滚动区域 - 显示在主画面区域 -->
          <view class="danmaku-container" :class="{ 'fullscreen-danmaku': isFullscreen }">
            <view 
              v-for="(item, index) in scrollingDanmakuList" 
              :key="index" 
              class="danmaku-scroll-item" 
              :style="getDanmakuStyle(item, index)"
              v-show="!item.hidden"
              @animationend="handleDanmakuEnd(item)"
            >
              {{ item.user }}：{{ item.content }}
            </view>
          </view>
          
          <!-- 全屏控制按钮 -->
          <view class="fullscreen-controls">
            <button class="fullscreen-btn" @click="toggleFullscreen">
              {{ isFullscreen ? '退出全屏' : '全屏' }}
            </button>
          </view>
          
          <!-- 全屏弹幕输入区域 -->
          <view v-if="isFullscreen" class="fullscreen-danmaku-input">
            <input 
              class="fullscreen-message-input" 
              type="text" 
              v-model="inputMessage" 
              placeholder="发送弹幕..."
              @confirm="sendMessage"
              @keyup.enter="sendMessage"
            />
            <button class="fullscreen-send-btn" @click="sendMessage">发送</button>
          </view>
        </view>
      </view>
      
      <!-- 观众画面区域 -->
      <view class="audience-video-section">
        <text class="section-title">观众画面</text>
        <view class="audience-video-wrapper">
          <!-- 本地预览（观众端自己的流） -->
          <view v-if="localStream" class="remote-video-container">
            <view v-html="localVideoElement"></view>
            <text class="video-label remote-label">我的画面</text>
          </view>
          
          <!-- 观众视频播放区域 -->
          <view 
            v-for="stream in audienceStreams" 
            :key="stream.userId" 
            class="remote-video-container"
          >
            <!-- 有流时显示视频 -->
            <view v-if="stream.hasStream" v-html="getAudienceVideoElement(stream.userId)"></view>
            
            <!-- 无流时显示占位符 -->
            <view v-else class="audience-placeholder">
              <view class="placeholder-icon">👤</view>
              <text class="placeholder-text">等待推流中...</text>
            </view>
            
            <text class="video-label remote-label">观众 {{ stream.userId }}</text>
          </view>
          
          <!-- 当没有观众时显示占位符 -->
          <view v-if="audienceStreams.length === 0" class="scroll-placeholder">
            <text>暂无观众画面</text>
          </view>
        </view>
      </view>
      
      <!-- 弹幕列表区域 -->
      <view class="danmaku-list-section">
        <text class="section-title">弹幕列表</text>
        <scroll-view class="danmaku-list-wrapper" scroll-y>
          <view 
            v-for="(item, index) in danmakuList" 
            :key="index" 
            class="danmaku-history-item"
            :style="{ borderLeftColor: item.color }"
          >
            <text v-if="item.user" class="danmaku-history-user">{{ item.user }}：</text>
            <text class="danmaku-history-content">{{ item.content }}</text>
            <text class="danmaku-history-time">{{ formatTime(item.timestamp) }}</text>
          </view>
          
          <!-- 当没有弹幕时显示占位符 -->
          <view v-if="danmakuList.length === 0" class="danmaku-placeholder">
            <text>暂无弹幕消息</text>
          </view>
        </scroll-view>
      </view>
    </view>
    
    <!-- 弹幕发送区域 -->
    <view class="danmaku-input-section" :class="{ 'fullscreen-input': isFullscreen }">
      <view class="input-area">
        <view class="danmaku-switch" @click="toggleDanmaku">
          <text class="switch-text">弹幕</text>
          <view class="switch-icon" :class="{ active: isDanmakuEnabled }"></view>
        </view>
        <input 
          class="message-input" 
          type="text" 
          v-model="inputMessage" 
          placeholder="说点什么..."
          @confirm="sendMessage"
          @keyup.enter="sendMessage"
          @keyup.13="sendMessage"
        />
        <button class="send-btn" @click="sendMessage">发送</button>
      </view>
    </view>
    
    <!-- 全屏时的弹幕输入区域 -->
    <view v-if="isFullscreen" class="fullscreen-danmaku-input">
      <view class="fullscreen-input-area">
        <button class="danmaku-toggle-btn" @click="toggleDanmaku" :class="{ active: isDanmakuEnabled }">
          {{ isDanmakuEnabled ? '弹幕开' : '弹幕关' }}
        </button>
        <input 
          class="fullscreen-message-input" 
          type="text" 
          v-model="inputMessage" 
          placeholder="发送弹幕..."
          @confirm="sendMessage"
          @keyup.enter="sendMessage"
          @keyup.13="sendMessage"
        />
        <button class="fullscreen-send-btn" @click="sendMessage">发送</button>
      </view>
    </view>
    
    <view class="controls">
      <button @click="joinRoom" :disabled="isConnected" class="control-btn join-btn">
        {{ isConnected ? '已连接房间' : '加入房间' }}
      </button>
      <button @click="leaveRoom" :disabled="!isConnected" class="control-btn leave-btn">
        离开房间
      </button>
      <button @click="testDanmaku" class="control-btn test-btn">
        测试弹幕
      </button>
    </view>
    
    <view class="room-info">
      <input 
        type="text" 
        v-model="signalServerUrl" 
        placeholder="信令服务器地址"
        class="input-field"
      />
      <input 
        type="text" 
        v-model="roomId" 
        placeholder="房间ID"
        class="input-field"
      />
    </view>
    
    <view class="status-info">
      <text>状态: {{ statusText }}</text>
    </view>
    
    <!-- 签到弹窗 -->
    <view v-if="showAttendanceModal" class="attendance-modal-overlay" @click="closeAttendanceModal">
      <view class="attendance-modal" @click.stop>
        <view class="attendance-header">
          <text class="attendance-title">📋 签到通知</text>
          <text class="attendance-countdown">剩余时间: {{ attendanceCountdown }}秒</text>
        </view>
        
        <view class="attendance-content">
          <text class="attendance-message">播放者发起了签到，请确认是否参与签到</text>
        </view>
        
        <view class="attendance-actions">
          <button class="attendance-btn confirm-btn" @click="confirmAttendance">
            ✓ 确认签到
          </button>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
// 引入必要的库
export default {
  data() {
    return {
      // 连接相关
      signalServerUrl: 'http://1.94.105.36:3000',
      roomId: 'room1',
      isConnected: false,
      signalingConnection: null,
      
      // 流相关
      localStream: null,
      publisherSdk: null,
      audienceStreams: [], // 存储观众流信息
      audienceSdks: new Map(), // 使用Map存储观众SDK实例，key为userId
      connectedUsers: [], // 添加连接用户列表，用于占位
      
      // 状态相关
      status: 'idle', // idle, connecting, connected, error
      errorMessage: '',
      
      // WebRTC相关
      peerConnection: null,
      isPublishing: false,
      
      // 弹幕相关
      danmakuList: [], // 弹幕列表（历史记录）
      scrollingDanmakuList: [], // 滚动弹幕列表
      inputMessage: '', // 输入消息
      isDanmakuEnabled: true, // 弹幕开关
      danmakuScrollTop: 0, // 弹幕滚动位置
      
      // 弹幕设置
      danmakuColors: ['#ffffff', '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff'],
      selectedColor: '#ffffff',
      selectedSize: 'medium', // small, medium, large
      danmakuPosition: 'full', // full, top, bottom
      
      // WebSocket相关
      websocket: null,
      websocketConnected: false,
      websocketTask: null,
      
      // 签到相关
      showAttendanceModal: false,
      attendanceCountdown: 30,
      attendanceTimer: null,
      
      // 摄像头控制相关
      cameraEnabled: true, // 当前摄像头状态
      cameraControlPending: false, // 是否有待处理的摄像头控制指令
      lastCameraControlCommand: null, // 最后收到的摄像头控制指令
      
      // 全屏相关
      isFullscreen: false // 是否处于全屏状态
    }
  },
  
  computed: {
    // 状态文本
    statusText() {
      switch(this.status) {
        case 'idle': return '未连接'
        case 'connecting': return '正在连接...'
        case 'connected': return '已连接房间'
        case 'error': return '连接错误: ' + this.errorMessage
        default: return '未知状态'
      }
    },
    
    // 主播视频元素
    publisherVideoElement() {
      return `<video id="publisher_video" class="video-player" controls autoplay width="100%" height="300px" style="object-fit: contain; background-color: #000;"></video>`;
    },
    
    // 本地视频元素
    localVideoElement() {
      return `<video id="local_video" class="video-player" autoplay muted playsinline width="100%" height="200px" style="object-fit: contain; background-color: #000;"></video>`;
    }
  },
  
  mounted() {
    // 动态引入SDK文件
    this.loadScript('/static/js/adapter-7.4.0.min.js').then(() => {
      return this.loadScript('/static/js/winlin.utility.js');
    }).then(() => {
      return this.loadScript('/static/js/srs.sdk.js');
    }).then(() => {
      console.log('SRS SDK 加载完成');
    }).catch((error) => {
      console.error('加载SDK失败:', error);
    });
    
    // 连接WebSocket
    this.connectWebSocket();
    
    // 添加一些测试弹幕
    this.addTestDanmaku();
    
    // 监听全屏状态变化
    this.setupFullscreenListeners();
  },
  
  methods: {
    // 动态加载JavaScript文件
    loadScript(src) {
      return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = src;
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
      });
    },
    
    // 生成观众视频元素
    getAudienceVideoElement(userId) {
      const videoId = 'audience_video_' + userId;
      return `<video id="${videoId}" class="video-player" controls autoplay width="100%" height="150px" style="object-fit: contain; background-color: #000;"></video>`;
    },
    
    // 加入房间
    async joinRoom() {
      if (this.isConnected) return;
      
      if (!this.signalServerUrl || !this.roomId) {
        uni.showToast({
          title: '请输入信令服务器地址和房间ID',
          icon: 'none'
        });
        return;
      }
      
      try {
        this.status = 'connecting';
        
        // 连接信令服务器
        await this.connectSignalingServer();
        
        // 获取本地媒体流
        await this.getLocalStream();
        
        // 开始推流
        await this.startPublishing();
        
        this.status = 'connected';
        this.isConnected = true;
        
      } catch (error) {
        console.error('加入房间失败:', error);
        this.status = 'error';
        this.errorMessage = error.message;
        uni.showToast({
          title: '加入房间失败: ' + error.message,
          icon: 'none'
        });
      }
    },
    
    // 离开房间
    leaveRoom() {
      // 停止推流
      this.stopPublishing();
      
      // 停止所有观众流播放
      this.stopAllAudienceStreams();
      
      // 断开信令服务器连接
      if (this.signalingConnection) {
        this.signalingConnection.disconnect();
        this.signalingConnection = null;
      }
      
      // 停止本地流
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => track.stop());
        this.localStream = null;
      }
      
      this.status = 'idle';
      this.isConnected = false;
      this.audienceStreams = [];
      this.audienceSdks = new Map();
      this.connectedUsers = [];
    },
    
    // 添加单个观众流
    addSingleAudienceStream(userId) {
      console.log(`添加单个观众流: ${userId}`);
      
      // 检查是否已存在
      if (this.audienceStreams.find(stream => stream.userId === userId)) {
        console.log(`观众流 ${userId} 已存在，跳过添加`);
        return;
      }
      
      const streamInfo = {
        userId: userId,
        streamId: `${this.roomId}_player_${userId}`
      };
      
      this.audienceStreams.push(streamInfo);
      
      // 播放观众流
      this.$nextTick(() => {
        this.playAudienceStream(userId);
      });
    },
    
    // 移除单个观众流
    removeSingleAudienceStream(userId) {
      console.log(`移除单个观众流: ${userId}`);
      
      const index = this.audienceStreams.findIndex(stream => stream.userId === userId);
      if (index !== -1) {
        // 停止SDK
        const sdk = this.audienceSdks.get(userId);
        if (sdk) {
          sdk.close();
          this.audienceSdks.delete(userId);
        }
        
        // 移除流信息
        this.audienceStreams.splice(index, 1);
        console.log(`观众流 ${userId} 已移除`);
      } else {
        console.log(`观众流 ${userId} 不存在，无需移除`);
      }
    },
    
    // 连接信令服务器
    connectSignalingServer() {
      return new Promise((resolve, reject) => {
        import('socket.io-client').then((module) => {
          const io = module.io || module.default || module;
          
          this.signalingConnection = io(this.signalServerUrl, {
            transports: ['websocket', 'polling'],
            reconnection: true,
            reconnectionAttempts: 5,
            reconnectionDelay: 1000,
            timeout: 10000
          });
          
          // 连接成功
          this.signalingConnection.on('connect', () => {
            console.log('信令服务器连接成功');
            
            // 以player身份加入房间
            this.signalingConnection.emit('join-room', {
              roomId: this.roomId,
              role: 'player'
            });
            
            // 初始化摄像头控制监听器
            this.setupCameraControlListeners();
            
            resolve();
          });
          
          // 连接错误
          this.signalingConnection.on('connect_error', (error) => {
            console.error('信令服务器连接错误:', error);
            reject(new Error('信令服务器连接失败: ' + error.message));
          });
          
          // 监听房间信息
          this.signalingConnection.on('room-info', (data) => {
            console.log('房间信息:', data);
            if (data.hasPublisher) {
              // 自动播放主播流
              this.playPublisherStream();
            }
          });
          
          // 监听发布者流可用事件
          this.signalingConnection.on('publisher-stream-available', (data) => {
            console.log('发布者流可用:', data);
            // 播放主播流
            this.playPublisherStream();
          });
          
          // 监听player流可用事件
          this.signalingConnection.on('player-stream-available', (data) => {
            console.log('player流可用:', data);
            if (data.playerId !== this.signalingConnection.id) {
              // 更新用户流状态
              const user = this.connectedUsers.find(u => u.userId === data.playerId);
              if (user) {
                user.hasStream = true;
              }
              
              // 添加到观众列表
              this.addAudienceStream(data.playerId);
            }
          });
          
          // 监听player流不可用事件
          this.signalingConnection.on('player-stream-unavailable', (data) => {
            console.log('player流不可用:', data);
            
            // 更新用户流状态，但保留占位
            const user = this.connectedUsers.find(u => u.userId === data.playerId);
            if (user) {
              user.hasStream = false;
            }
            
            // 停止播放流，但保留占位
            const streamInfo = this.audienceStreams.find(stream => stream.userId === data.playerId);
            if (streamInfo) {
              const sdk = this.audienceSdks.get(data.playerId);
              if (sdk) {
                sdk.close();
                this.audienceSdks.delete(data.playerId);
              }
              // 标记为无流状态，但不移除
              streamInfo.hasStream = false;
            }
          });
          
          // 监听用户连接事件
          this.signalingConnection.on('user-connected', (data) => {
            console.log('新用户连接:', data);
            
            // 添加到连接用户列表（用于占位显示）
            const existingUser = this.connectedUsers.find(user => user.userId === data.userId);
            if (!existingUser) {
              this.connectedUsers.push({
                userId: data.userId,
                role: data.role,
                hasStream: false // 初始时没有流
              });
            }
            
            // 根据变更类型精确处理，避免全量刷新
            if (data.changeType === 'player_joined') {
              // 只处理player加入，不需要刷新所有视频
              console.log(`Player ${data.userId} 加入房间`);
              
              // 为新加入的观众添加占位
              this.addAudiencePlaceholder(data.userId);
            }
          });
          
          // 监听用户断开事件
          this.signalingConnection.on('user-disconnected', (data) => {
            console.log('用户断开:', data);
            
            // 从连接用户列表中移除
            const index = this.connectedUsers.findIndex(user => user.userId === data.userId);
            if (index !== -1) {
              this.connectedUsers.splice(index, 1);
            }
            
            // 根据变更类型精确处理，避免全量刷新
            if (data.changeType === 'player_left') {
              // 只移除特定用户的流，不刷新所有视频
              this.removeSingleAudienceStream(data.userId);
            }
          });
          
          // 监听错误
          this.signalingConnection.on('error', (data) => {
            console.error('信令服务器错误:', data);
          });
          
          // 监听签到请求
          this.signalingConnection.on('attendance-request', (data) => {
            console.log('收到签到请求:', data);
            this.showAttendanceRequest(data);
          });
          
          // 监听签到取消
          this.signalingConnection.on('attendance-cancelled', (data) => {
            console.log('签到已取消:', data);
            if (this.showAttendanceModal) {
              this.closeAttendanceModal();
              uni.showToast({
                title: '签到已取消',
                icon: 'none'
              });
            }
          });
          
        }).catch((error) => {
          reject(new Error('Socket.IO加载失败: ' + error.message));
        });
      });
    },
    
    // 获取本地媒体流
    async getLocalStream() {
      try {
        this.localStream = await navigator.mediaDevices.getUserMedia({
          audio: true,
          video: true
        });
        
        // 设置到本地视频元素
        this.$nextTick(() => {
          const localVideo = document.getElementById('local_video');
          if (localVideo) {
            localVideo.srcObject = this.localStream;
          }
        });
        
      } catch (error) {
        throw new Error('获取摄像头权限失败: ' + error.message);
      }
    },
    
    // 开始推流
    async startPublishing() {
      if (!this.localStream || !this.signalingConnection) {
        return;
      }
      
      try {
        // 创建RTCPeerConnection
        this.peerConnection = new RTCPeerConnection({
          iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
        });
        
        // 添加本地流
        this.localStream.getTracks().forEach(track => {
          this.peerConnection.addTrack(track, this.localStream);
        });
        
        // 创建offer
        const offer = await this.peerConnection.createOffer();
        await this.peerConnection.setLocalDescription(offer);
        
        // 发送player推流offer到信令服务器
        this.signalingConnection.emit('player-publish-offer', {
          sdp: offer.sdp,
          type: offer.type,
          roomId: this.roomId
        });
        
        // 监听player推流answer
        this.signalingConnection.on('player-publish-answer', (data) => {
          this.handlePublishAnswer(data);
        });
        
        this.isPublishing = true;
        
      } catch (error) {
        console.error('推流失败:', error);
        throw error;
      }
    },
    
    // 处理推流answer
    async handlePublishAnswer(data) {
      try {
        const answer = new RTCSessionDescription({
          type: 'answer',
          sdp: data.sdp
        });
        await this.peerConnection.setRemoteDescription(answer);
        console.log('推流连接建立成功');
      } catch (error) {
        console.error('处理推流answer失败:', error);
      }
    },
    
    // 停止推流
    stopPublishing() {
      if (this.peerConnection) {
        this.peerConnection.close();
        this.peerConnection = null;
      }
      this.isPublishing = false;
    },
    
    // 播放主播流
    async playPublisherStream() {
      try {
        // 创建SDK实例播放主播流
        if (this.publisherSdk) {
          this.publisherSdk.close();
        }
        
        this.publisherSdk = new SrsRtcWhipWhepAsync();
        
        // 构建播放URL
        const publisherStreamId = `${this.roomId}_publisher`;
        const playUrl = `http://1.94.105.36:1985/rtc/v1/whep/?app=live&stream=${publisherStreamId}`;
        
        // 开始播放
        await this.publisherSdk.play(playUrl);
        
        // 设置到视频元素
        this.$nextTick(() => {
          const publisherVideo = document.getElementById('publisher_video');
          if (publisherVideo) {
            publisherVideo.srcObject = this.publisherSdk.stream;
            publisherVideo.play().catch(error => {
              console.warn('主播视频播放被阻止:', error);
            });
          }
        });
        
        console.log('主播流播放成功');
        
      } catch (error) {
        console.error('播放主播流失败:', error);
      }
    },
    
    // 添加观众占位
    addAudiencePlaceholder(userId) {
      // 检查是否已存在
      if (this.audienceStreams.find(stream => stream.userId === userId)) {
        return;
      }
      
      const streamInfo = {
        userId: userId,
        streamId: `${this.roomId}_player_${userId}`,
        hasStream: false // 初始时没有流
      };
      
      this.audienceStreams.push(streamInfo);
    },
    
    // 添加观众流
    addAudienceStream(userId) {
      // 检查是否已存在占位
      const existingStream = this.audienceStreams.find(stream => stream.userId === userId);
      if (existingStream) {
        // 更新为有流状态
        existingStream.hasStream = true;
      } else {
        // 创建新的流信息
        const streamInfo = {
          userId: userId,
          streamId: `${this.roomId}_player_${userId}`,
          hasStream: true
        };
        this.audienceStreams.push(streamInfo);
      }
      
      // 播放观众流
      this.$nextTick(() => {
        this.playAudienceStream(userId);
      });
    },
    
    // 播放观众流
    async playAudienceStream(userId) {
      try {
        const streamInfo = this.audienceStreams.find(stream => stream.userId === userId);
        if (!streamInfo) return;
        
        // 创建SDK实例
        const sdk = new SrsRtcWhipWhepAsync();
        
        // 构建播放URL
        const playUrl = `http://1.94.105.36:1985/rtc/v1/whep/?app=live&stream=${streamInfo.streamId}`;
        
        // 开始播放
        await sdk.play(playUrl);
        
        // 保存SDK实例
        this.audienceSdks.set(userId, sdk);
        
        // 设置到视频元素
        const videoId = 'audience_video_' + userId;
        const videoElement = document.getElementById(videoId);
        if (videoElement) {
          videoElement.srcObject = sdk.stream;
          videoElement.play().catch(error => {
            console.warn('观众视频播放被阻止:', error);
          });
        }
        
        console.log('观众流播放成功:', userId);
        
      } catch (error) {
        console.error('播放观众流失败:', error);
      }
    },
    
    // 移除观众流
    removeAudienceStream(userId) {
      const index = this.audienceStreams.findIndex(stream => stream.userId === userId);
      if (index !== -1) {
        // 停止SDK
        const sdk = this.audienceSdks.get(userId);
        if (sdk) {
          sdk.close();
          this.audienceSdks.delete(userId);
        }
        
        // 移除流信息
        this.audienceStreams.splice(index, 1);
      }
    },
    
    // 停止所有观众流
    stopAllAudienceStreams() {
      this.audienceSdks.forEach(sdk => {
        if (sdk) {
          sdk.close();
        }
      });
      
      if (this.publisherSdk) {
        this.publisherSdk.close();
        this.publisherSdk = null;
      }
      
      this.audienceSdks.clear();
      this.audienceStreams = [];
    },
    
    // 格式化时间
    formatTime(timestamp) {
      if (!timestamp) return '';
      const date = new Date(timestamp);
      return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
    },
    
    // 添加弹幕到列表
    addDanmaku(content, user = '用户', color = '#ffffff') {
      const danmaku = {
        content: content,
        user: user,
        color: color,
        timestamp: Date.now()
      };
      this.danmakuList.push(danmaku);
      
      // 限制弹幕数量，避免过多影响性能
      if (this.danmakuList.length > 100) {
        this.danmakuList.shift();
      }
    },
    
    // 添加测试弹幕
    addTestDanmaku() {
      const testDanmaku = [
    
      ];
      
      testDanmaku.forEach((item, index) => {
        setTimeout(() => {
          this.addDanmaku(item.content, item.user, item.color);
          this.addScrollingDanmaku(item.content, item.user, item.color);
        }, index * 1000);
      });
    },
    
    // 添加滚动弹幕
    addScrollingDanmaku(content, user = '用户', color = '#ffffff') {
      const danmaku = {
        content: content,
        user: user,
        color: color,
        top: Math.floor(Math.random() * 300) + 100, // 随机高度，确保在可见区域
        fontSize: this.getFontSize(),
        timestamp: Date.now(),
        hidden: false
      };
      
      this.scrollingDanmakuList.push(danmaku);
      console.log('添加滚动弹幕:', danmaku.content, '位置:', danmaku.top);
      console.log('当前滚动弹幕列表长度:', this.scrollingDanmakuList.length);
      console.log('滚动弹幕列表:', this.scrollingDanmakuList);
      
      // 限制滚动弹幕数量，避免过多影响性能
      if (this.scrollingDanmakuList.length > 50) {
        this.scrollingDanmakuList.shift();
      }
    },
    
    // 获取字体大小
    getFontSize() {
      const fontSizeMap = {
        small: 12,
        medium: 16,
        large: 20
      };
      return fontSizeMap[this.selectedSize] || 16;
    },
    
    // 获取弹幕样式
    getDanmakuStyle(item, index) {
      return {
        color: item.color,
        fontSize: item.fontSize + 'px',
        top: item.top + 'rpx',
        left: '100%' // 从右侧开始
      };
    },
    
    // 处理弹幕动画结束
    handleDanmakuEnd(item) {
      try {
        item.hidden = true;
      } catch (e) {
        console.error('隐藏弹幕失败', e);
      }
    },
    
    // 切换弹幕开关
    toggleDanmaku() {
      this.isDanmakuEnabled = !this.isDanmakuEnabled;
    },
    
    // 发送消息
    sendMessage() {
      if (!this.inputMessage.trim()) {
        uni.showToast({
          title: '请输入弹幕内容',
          icon: 'none',
          duration: 1500
        });
        return;
      }
      
      // 优先使用WebSocket发送
      if (this.isDanmakuEnabled && this.websocketTask && this.websocketConnected) {
        const danmakuMessage = {
          type: 'danmaku',
          content: this.inputMessage,
          user: '用户' + Math.floor(Math.random() * 1000),
          toUserid: '103',
          timestamp: Date.now()
        };

        // 通过WebSocket发送弹幕
        this.websocketTask.send({
          data: JSON.stringify(danmakuMessage)
        });
        console.log('弹幕已通过WebSocket发送:', danmakuMessage);
        
        // 同时本地显示
        this.addDanmaku(this.inputMessage, '我', this.selectedColor);
        this.addScrollingDanmaku(this.inputMessage, '我', this.selectedColor);
      } else {
        // WebSocket不可用时，本地发送
        this.addDanmaku(this.inputMessage, '我', this.selectedColor);
        this.addScrollingDanmaku(this.inputMessage, '我', this.selectedColor);
        console.log('弹幕已本地发送:', this.inputMessage);
      }
      
      // 清空输入框
      this.inputMessage = '';
      
      // 显示发送成功提示
      uni.showToast({
        title: '弹幕发送成功',
        icon: 'success',
        duration: 1000
      });
    },
    
    // 连接WebSocket
    connectWebSocket() {
      try {
        const classId = '101'; // 替换为实际班级ID
        this.websocketTask = uni.connectSocket({
          url: `ws://localhost:9006/danmaku-ws?classId=${classId}`,
          success: () => {
            console.log('WebSocket连接请求已发送（班级ID: ' + classId + '）');
          },
          fail: (err) => {
            console.error('WebSocket连接失败:', err);
          }
        });

        // 监听WebSocket连接打开事件
        this.websocketTask.onOpen(() => {
          console.log('WebSocket连接已打开');
          this.websocketConnected = true;
        });

        // 监听WebSocket消息接收事件
        this.websocketTask.onMessage((res) => {
          try {
            let data = res.data;
            console.log('收到WebSocket消息:', res.data);
            
            // 检查是否是服务器回复的消息格式
            if (typeof data === 'string' && data.startsWith('服务器回复: ')) {
              const jsonStr = data.substring('服务器回复: '.length);
              data = JSON.parse(jsonStr);
            } else if (typeof data === 'string') {
              data = JSON.parse(data);
            }

            // 添加消息去重逻辑
            const isDuplicate = this.danmakuList.some(item =>
              item.timestamp === data.timestamp &&
              item.content === data.content
            );

            if (isDuplicate) {
              console.log('过滤重复消息:', data);
              return;
            }

            // 处理不同类型的WebSocket消息
            if (data.type === 'danmaku') {
              const danmakuItem = {
                content: data.content,
                top: Math.floor(Math.random() * 400) + 50,
                color: data.color || '#ffffff',
                fontSize: data.fontSize || this.getFontSize(),
                user: data.user || data.userName,
                position: data.position || 'full',
                timestamp: data.timestamp || Date.now()
              };

              if (danmakuItem.content && danmakuItem.content.trim()) {
                // 添加到历史弹幕列表
                this.addDanmaku(danmakuItem.content, danmakuItem.user, danmakuItem.color);
                // 添加到滚动弹幕列表
                this.addScrollingDanmaku(danmakuItem.content, danmakuItem.user, danmakuItem.color);
                console.log('WebSocket弹幕已添加:', danmakuItem.content);
              }
            }
            // 处理AI助手回复
            else if (data.type === 'ai_reply') {
              const aiDanmaku = {
                content: data.content,
                top: Math.floor(Math.random() * 400) + 50,
                color: '#00ff00', // AI回复使用绿色
                fontSize: this.getFontSize(),
                position: data.position || this.danmakuPosition,
                user: 'AI助手',
                timestamp: data.timestamp || Date.now()
              };

              if (aiDanmaku.content && aiDanmaku.content.trim()) {
                this.addDanmaku(aiDanmaku.content, aiDanmaku.user, aiDanmaku.color);
                this.addScrollingDanmaku(aiDanmaku.content, aiDanmaku.user, aiDanmaku.color);
              }
            }
          } catch (e) {
            // 如果不是JSON格式，则作为普通文本处理
            console.log('收到WebSocket文本消息:', res.data);

            const isDuplicate = this.danmakuList.some(item =>
              item.content === res.data &&
              (Date.now() - (item.timestamp || 0)) < 1000
            );

            if (isDuplicate) {
              console.log('过滤重复文本消息:', res.data);
              return;
            }

            const danmakuItem = {
              content: res.data,
              top: Math.floor(Math.random() * 400) + 50,
              color: '#ffffff',
              fontSize: this.getFontSize(),
              user: '系统',
              position: 'full',
              timestamp: Date.now()
            };

            if (danmakuItem.content && danmakuItem.content.trim()) {
              this.addDanmaku(danmakuItem.content, danmakuItem.user, danmakuItem.color);
              this.addScrollingDanmaku(danmakuItem.content, danmakuItem.user, danmakuItem.color);
            }
          }
        });

        // 监听WebSocket关闭事件
        this.websocketTask.onClose(() => {
          console.log('WebSocket连接已关闭');
          this.websocketConnected = false;
        });

        // 监听WebSocket错误事件
        this.websocketTask.onError((err) => {
          console.error('WebSocket错误:', err);
          this.websocketConnected = false;
        });
      } catch (error) {
        console.error('WebSocket连接初始化失败:', error);
      }
    },
    
    // 测试弹幕方法
    testDanmaku() {
      const testMessages = ['测试弹幕1', '666666', '主播加油！', '学到了', '支持支持！'];
      const randomMessage = testMessages[Math.floor(Math.random() * testMessages.length)];
      
      this.addDanmaku(randomMessage, '测试用户', this.selectedColor);
      this.addScrollingDanmaku(randomMessage, '测试用户', this.selectedColor);
      
      uni.showToast({
        title: '测试弹幕已发送',
        icon: 'success',
        duration: 1000
      });
    },
    
    // 显示签到弹窗
    showAttendanceRequest(data) {
      console.log('收到签到请求:', data);
      this.showAttendanceModal = true;
      this.attendanceCountdown = 30;
      
      // 开始倒计时
      this.attendanceTimer = setInterval(() => {
        this.attendanceCountdown--;
        if (this.attendanceCountdown <= 0) {
          this.closeAttendanceModal();
        }
      }, 1000);
      
      // 播放提示音或震动
      uni.vibrateShort();
    },
    
    // 确认签到
    confirmAttendance() {
      if (this.signalingConnection) {
        this.signalingConnection.emit('attendance-response', {
          roomId: this.roomId,
          attended: true
        });
        
        console.log('已确认签到');
        uni.showToast({
          title: '签到成功！',
          icon: 'success'
        });
      }
      
      this.closeAttendanceModal();
    },
    
    // 关闭签到弹窗
    closeAttendanceModal() {
      this.showAttendanceModal = false;
      
      // 清理倒计时
      if (this.attendanceTimer) {
        clearInterval(this.attendanceTimer);
        this.attendanceTimer = null;
      }
      
      // 如果是超时关闭，发送未确认响应
      if (this.attendanceCountdown <= 0 && this.signalingConnection) {
        this.signalingConnection.emit('attendance-response', {
          roomId: this.roomId,
          attended: false
        });
        console.log('签到超时，已发送未确认响应');
      }
    },
    
    // 处理摄像头控制指令
    handleCameraControlCommand(data) {
      const { roomId, publisherId, action, timestamp } = data;
      
      console.log('收到摄像头控制指令:', data);
      
      // 验证房间ID
      if (roomId !== this.roomId) {
        console.warn('忽略其他房间的摄像头控制指令');
        return;
      }
      
      // 记录控制指令
      this.lastCameraControlCommand = data;
      this.cameraControlPending = true;
      
      // 执行摄像头控制
      this.executeCameraControl(action)
        .then((success) => {
          // 发送响应给服务器
          this.sendCameraControlResponse(action, success, null);
        })
        .catch((error) => {
          console.error('执行摄像头控制失败:', error);
          // 发送失败响应给服务器
          this.sendCameraControlResponse(action, false, error.message);
        })
        .finally(() => {
          this.cameraControlPending = false;
        });
    },
    
    // 执行摄像头控制
    async executeCameraControl(action) {
      try {
        if (action === 'enable') {
          // 开启摄像头
          if (!this.cameraEnabled) {
            await this.enableCamera();
            this.cameraEnabled = true;
            uni.showToast({
              title: '摄像头已开启',
              icon: 'success'
            });
          }
          return true;
        } else if (action === 'disable') {
          // 关闭摄像头
          if (this.cameraEnabled) {
            await this.disableCamera();
            this.cameraEnabled = false;
            uni.showToast({
              title: '摄像头已关闭',
              icon: 'none'
            });
          }
          return true;
        }
        return false;
      } catch (error) {
        console.error('摄像头控制操作失败:', error);
        throw error;
      }
    },
    
    // 开启摄像头
    async enableCamera() {
      try {
        // 如果已有本地流，先停止
        if (this.localStream) {
          this.stopLocalStream();
        }
        
        // 重新获取媒体流
        await this.startLocalStream();
        
        console.log('摄像头已开启');
      } catch (error) {
        console.error('开启摄像头失败:', error);
        throw new Error('无法开启摄像头: ' + error.message);
      }
    },
    
    // 关闭摄像头
    async disableCamera() {
      try {
        // 停止本地流
        this.stopLocalStream();
        
        console.log('摄像头已关闭');
      } catch (error) {
        console.error('关闭摄像头失败:', error);
        throw new Error('无法关闭摄像头: ' + error.message);
      }
    },

    // 启动本地媒体流
    async startLocalStream() {
      try {
        this.localStream = await navigator.mediaDevices.getUserMedia({
          audio: true,
          video: true
        });
        
        // 设置到本地视频元素
        this.$nextTick(() => {
          const localVideo = document.getElementById('local_video');
          if (localVideo) {
            localVideo.srcObject = this.localStream;
          }
        });
        
        console.log('本地媒体流已启动');
      } catch (error) {
        console.error('启动本地媒体流失败:', error);
        throw new Error('获取摄像头权限失败: ' + error.message);
      }
    },

    // 停止本地媒体流
    stopLocalStream() {
      try {
        if (this.localStream) {
          this.localStream.getTracks().forEach(track => {
            track.stop();
          });
          this.localStream = null;
          
          // 清除本地视频元素
          this.$nextTick(() => {
            const localVideo = document.getElementById('local_video');
            if (localVideo) {
              localVideo.srcObject = null;
            }
          });
          
          console.log('本地媒体流已停止');
        }
      } catch (error) {
        console.error('停止本地媒体流失败:', error);
        throw error;
      }
    },
    
    // 发送摄像头控制响应
    sendCameraControlResponse(action, success, error) {
      if (!this.signalingConnection) {
        console.error('信令连接未建立，无法发送摄像头控制响应');
        return;
      }
      
      const responseData = {
        roomId: this.roomId,
        action: action,
        success: success,
        error: error
      };
      
      // 发送Socket.IO事件
      this.signalingConnection.emit('camera-control-response', responseData);
      
      console.log('摄像头控制响应已发送:', responseData);
    },
    
    // 初始化摄像头控制事件监听
    setupCameraControlListeners() {
      if (!this.signalingConnection) {
        console.error('信令连接未建立，无法设置摄像头控制监听器');
        return;
      }
      
      // 监听摄像头控制指令
      this.signalingConnection.on('camera-control-command', (data) => {
        this.handleCameraControlCommand(data);
      });
      
      console.log('摄像头控制事件监听器已设置');
    },
    
    // 切换全屏状态
    toggleFullscreen() {
      this.isFullscreen = !this.isFullscreen;
      
      if (this.isFullscreen) {
        // 进入全屏
        this.enterFullscreen();
      } else {
        // 退出全屏
        this.exitFullscreen();
      }
    },
    
    // 进入全屏
    enterFullscreen() {
      try {
        const videoContainer = document.querySelector('.main-video-wrapper');
        if (videoContainer) {
          if (videoContainer.requestFullscreen) {
            videoContainer.requestFullscreen();
          } else if (videoContainer.webkitRequestFullscreen) {
            videoContainer.webkitRequestFullscreen();
          } else if (videoContainer.mozRequestFullScreen) {
            videoContainer.mozRequestFullScreen();
          } else if (videoContainer.msRequestFullscreen) {
            videoContainer.msRequestFullscreen();
          }
          
          // 全屏后调整视频尺寸
          this.$nextTick(() => {
            this.adjustVideoForFullscreen();
          });
        }
      } catch (error) {
        console.error('进入全屏失败:', error);
        // 如果浏览器全屏失败，使用自定义全屏
        this.isFullscreen = true;
        this.adjustVideoForFullscreen();
      }
    },
    
    // 退出全屏
    exitFullscreen() {
      try {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen();
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen();
        }
      } catch (error) {
        console.error('退出全屏失败:', error);
        // 如果浏览器全屏失败，使用自定义全屏
        this.isFullscreen = false;
      }
    },
    
    // 设置全屏状态监听
    setupFullscreenListeners() {
      // 监听全屏状态变化
      const fullscreenChangeEvents = [
        'fullscreenchange',
        'webkitfullscreenchange',
        'mozfullscreenchange',
        'MSFullscreenChange'
      ];
      
      fullscreenChangeEvents.forEach(event => {
        document.addEventListener(event, () => {
          this.handleFullscreenChange();
        });
      });
    },
    
    // 处理全屏状态变化
    handleFullscreenChange() {
      const isCurrentlyFullscreen = !!(
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement
      );
      
      this.isFullscreen = isCurrentlyFullscreen;
      console.log('全屏状态变化:', this.isFullscreen);
      
      // 全屏状态变化时调整视频尺寸
      if (this.isFullscreen) {
        this.$nextTick(() => {
          this.adjustVideoForFullscreen();
        });
      } else {
        this.$nextTick(() => {
          this.resetVideoSize();
        });
      }
    },
    
    // 调整视频为全屏尺寸
    adjustVideoForFullscreen() {
      const videoElement = document.getElementById('publisher_video');
      if (videoElement) {
        videoElement.style.width = '100vw';
        videoElement.style.height = '100vh';
        videoElement.style.objectFit = 'cover';
        videoElement.style.position = 'fixed';
        videoElement.style.top = '0';
        videoElement.style.left = '0';
        videoElement.style.zIndex = '999';
      }
    },
    
    // 重置视频尺寸
    resetVideoSize() {
      const videoElement = document.getElementById('publisher_video');
      if (videoElement) {
        videoElement.style.width = '100%';
        videoElement.style.height = '300px';
        videoElement.style.objectFit = 'contain';
        videoElement.style.position = 'relative';
        videoElement.style.top = 'auto';
        videoElement.style.left = 'auto';
        videoElement.style.zIndex = 'auto';
      }
    }
  },
  
  beforeDestroy() {
    // 页面销毁前清理所有资源
    this.leaveRoom();
    
    // 关闭WebSocket连接
    if (this.websocketTask) {
      this.websocketTask.close();
      console.log('WebSocket连接已关闭');
    }
    
    // 清理签到定时器
    if (this.attendanceTimer) {
      clearInterval(this.attendanceTimer);
      this.attendanceTimer = null;
    }
  },
  

}
</script>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #1a1a1a;
  color: #ffffff;
}

.header {
  text-align: center;
  padding: 20rpx 0;
  background-color: #2a2a2a;
  border-bottom: 1rpx solid #333;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  color: #ffffff;
}

.main-content {
  flex: 1;
  display: flex;
  flex-direction: row;
  background-color: #1a1a1a;
  overflow: hidden;
}

.main-video-section, .audience-video-section, .danmaku-list-section {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.main-video-section {
  flex: 4;
  border-right: 2rpx solid #333;
  padding: 10rpx;
  box-sizing: border-box;
  background-color: #1a1a1a;
}

.audience-video-section {
  flex: 1;
  border-right: 2rpx solid #333;
  padding: 10rpx;
  box-sizing: border-box;
  background-color: #1a1a1a;
}

.danmaku-list-section {
  flex: 1;
  padding: 10rpx;
  box-sizing: border-box;
  background-color: #1a1a1a;
}

.section-title {
  color: #fff;
  font-size: 28rpx;
  font-weight: bold;
  padding: 10rpx 0;
  text-align: center;
  background-color: #222;
  border-radius: 5rpx;
  margin-bottom: 10rpx;
}

.main-video-wrapper, .audience-video-wrapper, .danmaku-list-wrapper {
  flex: 1;
  overflow: hidden;
  position: relative;
}

.main-video-wrapper {
  height: calc(100% - 100rpx);
}

.audience-video-wrapper {
  overflow-y: auto;
}

.danmaku-list-wrapper {
  overflow-y: auto;
  background-color: #222;
  border-radius: 5rpx;
  padding: 10rpx;
}

.main-video-container, .remote-video-container {
  position: relative;
  width: 100%;
  height: 100%;
  margin-bottom: 10rpx;
  border: 1rpx solid #444;
  border-radius: 5rpx;
  overflow: hidden;
  background-color: #000;
}

.remote-video-container {
  height: 500rpx;
  margin-bottom: 20rpx;
}

.video-player {
  width: 100%;
  height: 100%;
  background-color: #000;
  border-radius: 10rpx;
}

.video-label {
  position: absolute;
  top: 5rpx;
  left: 5rpx;
  background-color: rgba(0,0,0,0.5);
  color: white;
  padding: 2rpx 10rpx;
  border-radius: 5rpx;
  font-size: 24rpx;
}

.local-label {
  background-color: rgba(0,122,255,0.7);
}

.remote-label {
  background-color: rgba(255,149,0,0.7);
}

.placeholder, .scroll-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  background-color: #333;
}

.scroll-placeholder {
  position: relative;
  background-color: #222;
}

.room-info {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  margin-bottom: 20rpx;
  padding: 0 20rpx;
}

.input-field {
  height: 80rpx;
  padding: 0 20rpx;
  border: 1rpx solid #333;
  border-radius: 10rpx;
  font-size: 28rpx;
  background-color: #2a2a2a;
  color: #ffffff;
}

.input-field::placeholder {
  color: #999;
}

.status-info {
  text-align: center;
  color: #666;
  font-size: 28rpx;
  padding: 20rpx;
  background-color: #2a2a2a;
}

.audience-placeholder {
  width: 100%;
  height: 100%;
  background: #f5f5f5;
  border: 2rpx dashed #ddd;
  border-radius: 8rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 200rpx;
}

.placeholder-icon {
  font-size: 60rpx;
  color: #ccc;
  margin-bottom: 10rpx;
}

.placeholder-text {
  font-size: 24rpx;
  color: #999;
  text-align: center;
}

/* 弹幕历史列表样式 */
.danmaku-history-item {
  display: flex;
  align-items: center;
  padding: 10rpx 0;
  border-left: 6rpx solid #ffffff;
  margin-bottom: 10rpx;
  padding-left: 10rpx;
}

.danmaku-history-user {
  color: #007AFF;
  font-weight: bold;
  margin-right: 10rpx;
  font-size: 24rpx;
  white-space: nowrap;
}

.danmaku-history-content {
  flex: 1;
  color: #ffffff;
  font-size: 24rpx;
  margin-right: 10rpx;
  word-break: break-all;
}

.danmaku-history-time {
  color: #999;
  font-size: 20rpx;
  white-space: nowrap;
}

.danmaku-placeholder {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200rpx;
  color: #666;
  font-size: 24rpx;
}

/* 控制按钮样式 */
.controls {
  display: flex;
  justify-content: space-around;
  margin-bottom: 20rpx;
  gap: 20rpx;
  padding: 20rpx;
}

.control-btn {
  flex: 1;
  height: 80rpx;
  font-size: 32rpx;
  border-radius: 10rpx;
  border: none;
  color: white;
  font-weight: bold;
}

.join-btn {
  background-color: #007aff;
}

.join-btn:disabled {
  background-color: #ccc;
  color: #666;
}

.leave-btn {
  background-color: #ff3b30;
}

.leave-btn:disabled {
  background-color: #ccc;
  color: #666;
}

.test-btn {
  background-color: #34c759;
}

.test-btn:active {
  background-color: #2fb84d;
}

/* 弹幕发送区域样式 */
.danmaku-input-section {
  padding: 20rpx;
  background-color: #2a2a2a;
  border-top: 1rpx solid #333;
}

.danmaku-input-section .input-area {
  display: flex;
  align-items: center;
  gap: 20rpx;
}

.danmaku-switch {
  display: flex;
  align-items: center;
  gap: 10rpx;
}

.switch-text {
  color: #ffffff;
  font-size: 28rpx;
}

.switch-icon {
  width: 40rpx;
  height: 20rpx;
  background-color: #666;
  border-radius: 10rpx;
  position: relative;
  transition: background-color 0.3s;
}

.switch-icon.active {
  background-color: #007aff;
}

.switch-icon::after {
  content: '';
  position: absolute;
  top: 2rpx;
  left: 2rpx;
  width: 16rpx;
  height: 16rpx;
  background-color: #ffffff;
  border-radius: 50%;
  transition: transform 0.3s;
}

.switch-icon.active::after {
  transform: translateX(20rpx);
}

.danmaku-input-section .message-input {
  flex: 1;
  height: 60rpx;
  background-color: #3a3a3a;
  border-radius: 30rpx;
  padding: 0 20rpx;
  color: #ffffff;
  font-size: 28rpx;
  border: 1rpx solid #333;
}

.danmaku-input-section .message-input::placeholder {
  color: #999;
}

.danmaku-input-section .send-btn {
  height: 60rpx;
  padding: 0 30rpx;
  background-color: #007aff;
  color: white;
  border: none;
  border-radius: 30rpx;
  font-size: 28rpx;
  font-weight: bold;
}

/* 全屏时的弹幕输入区域 */
.danmaku-input-section.fullscreen-input {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1001;
  background-color: rgba(42, 42, 42, 0.95);
  backdrop-filter: blur(10px);
  padding: 20rpx;
  border-top: 1rpx solid rgba(255, 255, 255, 0.2);
}

/* 全屏时确保输入框可见 */
.danmaku-input-section.fullscreen-input .input-area {
  max-width: 800rpx;
  margin: 0 auto;
}

.danmaku-input-section.fullscreen-input .message-input {
  background-color: rgba(58, 58, 58, 0.9);
  border: 1rpx solid rgba(255, 255, 255, 0.3);
}

.danmaku-input-section.fullscreen-input .send-btn {
  background-color: #007aff;
  border: 1rpx solid rgba(255, 255, 255, 0.2);
}

/* 全屏弹幕输入区域 */
.fullscreen-danmaku-input {
  position: fixed;
  bottom: 30rpx;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1004;
  background-color: rgba(0, 0, 0, 0.85);
  border-radius: 50rpx;
  padding: 15rpx 25rpx;
  backdrop-filter: blur(15px);
  border: 2rpx solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.5);
  pointer-events: auto;
}

.fullscreen-input-area {
  display: flex;
  align-items: center;
  gap: 15rpx;
}

.fullscreen-message-input {
  width: 450rpx;
  height: 70rpx;
  background-color: rgba(255, 255, 255, 0.15);
  border: 2rpx solid rgba(255, 255, 255, 0.4);
  border-radius: 35rpx;
  padding: 0 25rpx;
  color: #ffffff;
  font-size: 30rpx;
  transition: all 0.3s ease;
}

.fullscreen-message-input:focus {
  border-color: #007aff;
  background-color: rgba(255, 255, 255, 0.2);
  outline: none;
}

.fullscreen-message-input::placeholder {
  color: rgba(255, 255, 255, 0.7);
  font-size: 28rpx;
}

.fullscreen-send-btn {
  height: 70rpx;
  padding: 0 35rpx;
  background-color: #007aff;
  color: white;
  border: 2rpx solid #007aff;
  border-radius: 35rpx;
  font-size: 30rpx;
  font-weight: bold;
  min-width: 120rpx;
  cursor: pointer;
  transition: all 0.3s ease;
}

.fullscreen-send-btn:hover {
  background-color: #0056b3;
  border-color: #0056b3;
  transform: scale(1.05);
}

.fullscreen-send-btn:active {
  transform: scale(0.95);
}

/* 全屏控制按钮 */
.fullscreen-controls {
  position: absolute;
  top: 10rpx;
  right: 10rpx;
  z-index: 1003;
}

/* 全屏时的控制按钮 */
.main-video-wrapper:fullscreen .fullscreen-controls,
.main-video-wrapper:-webkit-full-screen .fullscreen-controls,
.main-video-wrapper:-moz-full-screen .fullscreen-controls,
.main-video-wrapper:-ms-fullscreen .fullscreen-controls {
  position: fixed;
  top: 20rpx;
  right: 20rpx;
  z-index: 1003;
}

.fullscreen-btn {
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  border: 2rpx solid rgba(255, 255, 255, 0.5);
  border-radius: 8rpx;
  padding: 15rpx 25rpx;
  font-size: 28rpx;
  font-weight: bold;
  backdrop-filter: blur(10px);
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 120rpx;
  text-align: center;
}

.fullscreen-btn:hover {
  background-color: rgba(0, 0, 0, 0.9);
  border-color: rgba(255, 255, 255, 0.8);
  transform: scale(1.05);
}

.fullscreen-btn:active {
  transform: scale(0.95);
}

/* 全屏弹幕输入区域 */
.fullscreen-danmaku-input {
  position: fixed;
  bottom: 30rpx;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1005;
  background-color: rgba(0, 0, 0, 0.3);
  border-radius: 50rpx;
  padding: 15rpx 25rpx;
  backdrop-filter: blur(15px);
  border: 2rpx solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.2);
  display: flex;
  align-items: center;
  gap: 15rpx;
}

.fullscreen-message-input {
  width: 400rpx;
  height: 60rpx;
  background-color: rgba(255, 255, 255, 0.15);
  border: 2rpx solid rgba(255, 255, 255, 0.4);
  border-radius: 30rpx;
  padding: 0 20rpx;
  color: #ffffff;
  font-size: 28rpx;
  outline: none;
}

.fullscreen-message-input:focus {
  border-color: #007aff;
  background-color: rgba(255, 255, 255, 0.25);
}

.fullscreen-message-input::placeholder {
  color: rgba(255, 255, 255, 0.6);
}

.fullscreen-send-btn {
  height: 60rpx;
  padding: 0 30rpx;
  background-color: rgba(0, 122, 255, 0.8);
  color: white;
  border: 2rpx solid rgba(0, 122, 255, 0.8);
  border-radius: 30rpx;
  font-size: 28rpx;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s ease;
}

.fullscreen-send-btn:hover {
  background-color: rgba(0, 91, 179, 0.9);
  border-color: rgba(0, 91, 179, 0.9);
}

.fullscreen-send-btn:active {
  transform: scale(0.95);
}

/* 全屏时的视频容器 */
.main-video-wrapper:fullscreen {
  background-color: #000;
  width: 100vw !important;
  height: 100vh !important;
  display: flex;
  align-items: center;
  justify-content: center;
}

.main-video-wrapper:-webkit-full-screen {
  background-color: #000;
  width: 100vw !important;
  height: 100vh !important;
  display: flex;
  align-items: center;
  justify-content: center;
}

.main-video-wrapper:-moz-full-screen {
  background-color: #000;
  width: 100vw !important;
  height: 100vh !important;
  display: flex;
  align-items: center;
  justify-content: center;
}

.main-video-wrapper:-ms-fullscreen {
  background-color: #000;
  width: 100vw !important;
  height: 100vh !important;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 全屏时的视频元素 */
.main-video-wrapper:fullscreen .main-video-container {
  width: 100vw !important;
  height: 100vh !important;
  max-width: 100vw !important;
  max-height: 100vh !important;
}

.main-video-wrapper:-webkit-full-screen .main-video-container {
  width: 100vw !important;
  height: 100vh !important;
  max-width: 100vw !important;
  max-height: 100vh !important;
}

.main-video-wrapper:-moz-full-screen .main-video-container {
  width: 100vw !important;
  height: 100vh !important;
  max-width: 100vw !important;
  max-height: 100vh !important;
}

.main-video-wrapper:-ms-fullscreen .main-video-container {
  width: 100vw !important;
  height: 100vh !important;
  max-width: 100vw !important;
  max-height: 100vh !important;
}

/* 全屏时的视频播放器 */
.main-video-wrapper:fullscreen .video-player {
  width: 100vw !important;
  height: 100vh !important;
  object-fit: cover !important;
}

.main-video-wrapper:-webkit-full-screen .video-player {
  width: 100vw !important;
  height: 100vh !important;
  object-fit: cover !important;
}

.main-video-wrapper:-moz-full-screen .video-player {
  width: 100vw !important;
  height: 100vh !important;
  object-fit: cover !important;
}

.main-video-wrapper:-ms-fullscreen .video-player {
  width: 100vw !important;
  height: 100vh !important;
  object-fit: cover !important;
}

/* 弹幕滚动样式 - 显示在主画面区域 */
.danmaku-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 50;
}

/* 全屏时的弹幕容器 */
.danmaku-container.fullscreen-danmaku {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  z-index: 1000;
}

.danmaku-scroll-item {
  position: absolute;
  white-space: nowrap;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
  animation: danmaku 8s linear;
  animation-fill-mode: forwards;
  z-index: 100;
  pointer-events: none;
  color: #ffffff;
  font-size: 16px;
  font-weight: bold;
}

/* 弹幕滚动动画 */
@keyframes danmaku {
  0% {
    transform: translateX(100vw);
    opacity: 0;
  }
  5% {
    opacity: 1;
  }
  95% {
    opacity: 1;
  }
  100% {
    transform: translateX(-100vw);
    opacity: 0;
    visibility: hidden;
  }
}

/* 签到弹窗样式 */
.attendance-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.attendance-modal {
  background-color: #ffffff;
  border-radius: 20rpx;
  padding: 40rpx;
  margin: 40rpx;
  max-width: 600rpx;
  width: 90%;
  box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.3);
  animation: modalSlideIn 0.3s ease-out;
}

@keyframes modalSlideIn {
  from {
    transform: translateY(-50rpx);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.attendance-header {
  text-align: center;
  margin-bottom: 30rpx;
  border-bottom: 2rpx solid #f0f0f0;
  padding-bottom: 20rpx;
}

.attendance-title {
  font-size: 36rpx;
  font-weight: bold;
  color: #333333;
  display: block;
  margin-bottom: 10rpx;
}

.attendance-countdown {
  font-size: 28rpx;
  color: #ff6b6b;
  font-weight: bold;
  display: block;
}

.attendance-content {
  text-align: center;
  margin-bottom: 40rpx;
}

.attendance-message {
  font-size: 32rpx;
  color: #666666;
  line-height: 1.5;
  display: block;
}

.attendance-actions {
  display: flex;
  justify-content: space-around;
  gap: 20rpx;
}

.attendance-btn {
  flex: 1;
  height: 80rpx;
  border-radius: 40rpx;
  font-size: 32rpx;
  font-weight: bold;
  border: none;
  cursor: pointer;
  transition: all 0.3s ease;
}

.confirm-btn {
  background-color: #4CAF50;
  color: white;
}

.confirm-btn:hover {
  background-color: #45a049;
  transform: translateY(-2rpx);
}


</style>